RNOAA R test for the ISD/DS3505 Datasets
Pardon the typos; they are legion.
To begin with we will use the “rnoaa” library.
It is also handy to have the “lubridate” library to manage the time coordinate data.
ISD Parsing is sone with the “isdparser”
You will need to install all three
I also included the “openair” library for wind roses
Something to be aware of before we start.
These are an merger of several report message types, METARs (Hourlies), SPECIs (special reports that supplement the METARs), and 3-hrly but more comprehensive SYNOPs. Most are derived for use at airports and thus have more than one cloud field (low, middle and high). The data archiving is designed to house any of the messages in one single record.
For some fields like temperature, pressure, humidity and wind speed, this isn’t too much of a problem. But for other fields like cloud and precip and significant weather that will vary with the type of report message.
library("lubridate")
library("isdparser")
library("rnoaa")
library("openair")
To target a given station location you will need two catalog codes
The USAF Code and the WBAN code.
If you didn’t work in the old Asheville Federal Building in the 80s before they moved and don’t know what file cabinet the station history info is kept, there is hope.
If you have the latitude and longitude and radius in KM you can pull those fields from using the isd_station_search function.
stations_near_KRAP = isd_stations_search(lat = 44, # degrees_north
lon = -103, # degrees_east
radius = 100) # km
print(stations_near_KRAP)
So for Rapid City Regional Airport (KRAP) which probably has the best reporting fidelity since it’s a First Order Station for NOAA, and for your period, you will want to use the following stationID pair.
I am not sure as to the quality or reliability of Elsworth (KRCA), Custer (KCUT) or Spearfish (KSPF) since they are not affiliated with an NWS office.
krap_usaf = 726620
krap_wban = 24090
krap_year = 2010
station_name_label = paste("Rapid City",
krap_year)
output_file_name = paste("KRAP",
krap_year,
".csv",
sep="")
To extract the data (and this can take a few minutes since you are digging on the NOAA servers…)
use the isd command following this example. The original data is kept in a compressed “tarball” with one tarball per year.
This also has the option for multiprocessing but you probably don’t need it.
KRAP_data = isd(usaf = krap_usaf, # your usaf number
wban = krap_wban, # your wban number
year = krap_year, # your year
progress=TRUE) # shows prograss as you go
found in cache
print(KRAP_data)
You will want to fix the date. In the ISD format it is split between calendar day (UTC time always) and clock hour (UTC time always)
This can be done with the lubridate function ymd_hm()
KRAP_data$date_time = ymd_hm(sprintf("%s %s",
as.character(KRAP_data$date),
KRAP_data$time))
KRAP_data$date = KRAP_data$date_time
The data is parsed as strings. So you’ll have to use the as.numeric() a lot Missing fields are typically ID’ed as 9999 in the original data
KRAP_data$temperature[KRAP_data$temperature == "+9999"] = NA
KRAP_data$temperature_dewpoint[KRAP_data$temperature_dewpoint == "+9999"] = NA
KRAP_data$air_pressure[KRAP_data$air_pressure == "99999"] = NA
KRAP_data$wind_speed[KRAP_data$wind_speed == "9999"] = NA
KRAP_data$wind_direction[KRAP_data$wind_direction == "999"] = NA
Some of these fields, but not all, are managed with the isd_transform() function with respect to scaling
temp/dew point (deg C) converted from 10ths of degree mean sea level pressure (hPa) converted from 10ths of hPa wind speed (m s-1) converted from 10ths of m s-1 wind direction (compass decimal degrees)
Precip is also processed but this data set is an merger of both hourly, 3-hrly, 6-hrly, 12-hrly, 24-hrly data depending on the report message that’s being archived and I am not sure you will want that, especially if you can get Hourly Precip Data from another source
KRAP_data = isd_transform(KRAP_data)
unknown timezone '%Y%m%d'
# patch the wind direction so it's 0 degrees when the wind speed is missing
KRAP_data$wind_direction[KRAP_data$wind_speed == 0] = 0
Cloud Cover is held in several positions in the dataset. Once again this is because the data is designed for use for aerodrome use.
I am setting it up to give you the “GF1 group” which is the total cloud cover for all flight levels. These fields are often archived in “octaves” or eights and I’ll be converting them to fractions for you. IN cases of “obscured sky” caused by fog or smoke, I will label it 100% for total obscured sky or 50% covered for partial obscured skies.
KRAP_data$GF1_total_cloud_cover_fraction = as.numeric(KRAP_data$GF1_coverage)
# 00: None, SKC or CLR
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==00] = 0.00
# 01: One okta - 1/10 or less but not zero
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==01] = 1.0 / 8.0
# 02: Two oktas - 2/10 ‑ 3/10, or FEW
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==02] = 2.0 / 8.0
# 03: Three oktas - 4/10
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==03] = 3.0 / 8.0
# 04: Four oktas - 5/10, or SCT
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==04] = 4.0 / 8.0
# 05: Five oktas - 6/10
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==05] = 5.0 / 8.0
# 06: Six oktas - 7/10 ‑ 8/10
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==06] = 6.0 / 8.0
# 07: Seven oktas - 9/10 or more but not 10/10, or BKN
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==07] = 7.0 / 8.0
# 08: Eight oktas - 10/10, or OVC
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==08] = 8.0 / 8.0
# 09: Sky obscured, or cloud amount cannot be estimated
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==09] = 8.0 / 8.0
# 10: Partial obscuration
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==10] = 4.0 / 8.0
# 11: Thin scattered
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==11] = 2.0 / 8.0
# 12: Scattered
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==12] = 4.0 / 8.0
# 13: Dark scattered
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==13] = 5.0 / 8.0
# 14: Thin broken
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==14] = 6.0 / 8.0
# 15: Broken
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==15] = 7.0 / 8.0
# 16: Dark broken
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==16] = 8.0 / 8.0
# 17: Thin overcast
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==17] = 4.0 / 8.0
# 18: Overcast
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==18] = 8.0 / 8.0
# 19: Dark overcast
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==19] = 8.0 / 8.0
# 99: Missing
KRAP_data$GF1_total_cloud_cover_fraction[KRAP_data$GF1_total_cloud_cover_fraction==99] = NA
And to plot everything out…
Temperature
plot(x = KRAP_data$date_time,
y = KRAP_data$temperature,
type = "l",
col = "red",
lwd = 1.5,
cex.lab = 1.25,
xlab = "Date",
ylab = "Temperature (deg C)",
main = station_name_label)

Dew Point
plot(x = KRAP_data$date_time,
y = KRAP_data$temperature_dewpoint,
type = "l",
col = "darkgreen",
lwd = 1.5,
cex.lab = 1.25,
xlab = "Date",
ylab = "Dew Point (deg C)",
main = station_name_label)

Cloud Fraction
plot(x = KRAP_data$date_time,
y = KRAP_data$GF1_total_cloud_cover_fraction,
type = "l",
col = "grey",
lwd = 1.5,
cex.lab = 1.25,
xlab = "Date",
ylab = "Cloud Cover (fraction)",
main = station_name_label)

Pressure
plot(x = KRAP_data$date_time,
y = KRAP_data$air_pressure,
type = "l",
col = "blue",
lwd = 1.5,
cex.lab = 1.25,
xlab = "Date",
ylab = "MSL Pressure (mb)",
main = station_name_label)

Wind Speed
plot(x = KRAP_data$date_time,
y = KRAP_data$wind_speed,
type = "l",
col = "darkblue",
lwd = 1.5,
cex.lab = 1.25,
xlab = "Date",
ylab = "Wind Speed (m s-1)",
main = station_name_label)

Wind Rose
windrose_frame = data.frame(date = KRAP_data$date_time,
ws = KRAP_data$wind_speed,
wd = KRAP_data$wind_direction,
longitude = KRAP_data$longitude,
latitude = KRAP_data$latitude)
windRose(mydata = windrose_frame,
ws = "ws",
wd = "wd",
type = "year",
hemisphere = "northern",
main = station_name_label)

windRose(mydata = windrose_frame,
ws = "ws",
wd = "wd",
type = "season",
hemisphere = "northern",
main = station_name_label)

Finally let’s put everything into a single time frame since we have observations at several times. We can interpolate the data to the nearest hour.
We do this by first creating a regularly spaced time vector
start_date = as.POSIXct(paste(krap_year,
"-01-01 00:00:00 UTC",
sep=""),
tz = "UTC")
end_date = as.POSIXct(paste(krap_year,
"-12-31 00:00:00 UTC",
sep=""),
tz = "UTC")
hour_time = seq.POSIXt(from = start_date,
to = end_date,
by = "1 hour",
tz = "UTC")
We then interpolate between the various fields and frame them…
KRAP_time_series = data.frame(date = hour_time)
KRAP_time_series$temperature_degC = approx(x = KRAP_data$date_time,
y = KRAP_data$temperature,
method = "linear",
xout = hour_time)$y
KRAP_time_series$dewpoint_degC = approx(x = KRAP_data$date_time,
y = KRAP_data$temperature_dewpoint,
method = "linear",
xout = hour_time)$y
KRAP_time_series$cloud_fraction = approx(x = KRAP_data$date_time,
y = KRAP_data$GF1_total_cloud_cover_fraction,
method = "linear",
xout = hour_time)$y
KRAP_time_series$press_msl_hPa = approx(x = KRAP_data$date_time,
y = KRAP_data$air_pressure,
method = "linear",
xout = hour_time)$y
KRAP_time_series$wind_spd_ms = approx(x = KRAP_data$date_time,
y = KRAP_data$wind_speed,
method = "linear",
xout = hour_time)$y
KRAP_time_series$wind_dir_degrees = approx(x = KRAP_data$date_time,
y = KRAP_data$wind_direction,
method = "linear",
xout = hour_time)$y
print(KRAP_time_series)
And send it to an ASCII file
write.table(x = KRAP_time_series,
file = output_file_name,
sep =", ",
row.names = FALSE)
LS0tCnRpdGxlOiAicm5vYWEgIE5vdGVib29rIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpSTk9BQSBSIHRlc3QgZm9yIHRoZSBJU0QvRFMzNTA1IERhdGFzZXRzCgpQYXJkb24gdGhlIHR5cG9zOyB0aGV5IGFyZSBsZWdpb24uCgpUbyBiZWdpbiB3aXRoIHdlIHdpbGwgdXNlIHRoZSAicm5vYWEiIGxpYnJhcnkuCgpJdCBpcyBhbHNvIGhhbmR5IHRvIGhhdmUgdGhlICJsdWJyaWRhdGUiIGxpYnJhcnkgdG8gbWFuYWdlIHRoZSB0aW1lIGNvb3JkaW5hdGUgZGF0YS4gIAoKSVNEIFBhcnNpbmcgaXMgc29uZSB3aXRoIHRoZSAiaXNkcGFyc2VyIgoKWW91IHdpbGwgbmVlZCB0byBpbnN0YWxsIGFsbCB0aHJlZQoKSSBhbHNvIGluY2x1ZGVkICB0aGUgIm9wZW5haXIiIGxpYnJhcnkgZm9yIHdpbmQgcm9zZXMKClNvbWV0aGluZyB0byBiZSBhd2FyZSBvZiBiZWZvcmUgd2Ugc3RhcnQuICAKClRoZXNlIGFyZSBhbiBtZXJnZXIgb2Ygc2V2ZXJhbCByZXBvcnQgbWVzc2FnZSB0eXBlcywgTUVUQVJzIChIb3VybGllcyksIFNQRUNJcyAoc3BlY2lhbCByZXBvcnRzIHRoYXQgc3VwcGxlbWVudCB0aGUgTUVUQVJzKSwgYW5kIDMtaHJseSBidXQgbW9yZSBjb21wcmVoZW5zaXZlIFNZTk9Qcy4gIE1vc3QgYXJlIGRlcml2ZWQgZm9yIHVzZSBhdCBhaXJwb3J0cyBhbmQgdGh1cyBoYXZlIG1vcmUgdGhhbiBvbmUgY2xvdWQgZmllbGQgKGxvdywgbWlkZGxlIGFuZCBoaWdoKS4gVGhlIGRhdGEgYXJjaGl2aW5nIGlzIGRlc2lnbmVkIHRvIGhvdXNlIGFueSBvZiB0aGUgbWVzc2FnZXMgaW4gb25lIHNpbmdsZSByZWNvcmQuCgpGb3Igc29tZSBmaWVsZHMgbGlrZSB0ZW1wZXJhdHVyZSwgcHJlc3N1cmUsIGh1bWlkaXR5IGFuZCB3aW5kIHNwZWVkLCB0aGlzIGlzbid0IHRvbyBtdWNoIG9mIGEgcHJvYmxlbS4gIEJ1dCBmb3Igb3RoZXIgZmllbGRzIGxpa2UgY2xvdWQgYW5kIHByZWNpcCBhbmQgc2lnbmlmaWNhbnQgd2VhdGhlciB0aGF0IHdpbGwgdmFyeSB3aXRoIHRoZSB0eXBlIG9mIHJlcG9ydCBtZXNzYWdlLgoKYGBge3J9CmxpYnJhcnkoImx1YnJpZGF0ZSIpCmxpYnJhcnkoImlzZHBhcnNlciIpCmxpYnJhcnkoInJub2FhIikKbGlicmFyeSgib3BlbmFpciIpCmBgYAoKVG8gdGFyZ2V0IGEgZ2l2ZW4gc3RhdGlvbiBsb2NhdGlvbiB5b3Ugd2lsbCBuZWVkIHR3byBjYXRhbG9nIGNvZGVzCgpUaGUgVVNBRiBDb2RlIGFuZCB0aGUgV0JBTiBjb2RlLgoKSWYgeW91IGRpZG4ndCB3b3JrIGluIHRoZSBvbGQgQXNoZXZpbGxlIEZlZGVyYWwgQnVpbGRpbmcgaW4gdGhlIDgwcyBiZWZvcmUgdGhleSBtb3ZlZCBhbmQgZG9uJ3Qga25vdyB3aGF0IGZpbGUgY2FiaW5ldCB0aGUgc3RhdGlvbiBoaXN0b3J5IGluZm8gaXMga2VwdCwgdGhlcmUgaXMgaG9wZS4KCklmIHlvdSBoYXZlIHRoZSBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIGFuZCByYWRpdXMgaW4gS00geW91IGNhbiBwdWxsIHRob3NlIGZpZWxkcyBmcm9tICB1c2luZyB0aGUgaXNkX3N0YXRpb25fc2VhcmNoIGZ1bmN0aW9uLgoKYGBge3J9CnN0YXRpb25zX25lYXJfS1JBUCA9IGlzZF9zdGF0aW9uc19zZWFyY2gobGF0ICAgID0gICA0NCwgICMgZGVncmVlc19ub3J0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbiAgICA9IC0xMDMsICAjIGRlZ3JlZXNfZWFzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9ICAxMDApICAjIGttCgpwcmludChzdGF0aW9uc19uZWFyX0tSQVApCmBgYAoKU28gZm9yIFJhcGlkIENpdHkgUmVnaW9uYWwgQWlycG9ydCAoS1JBUCkgd2hpY2ggcHJvYmFibHkgaGFzIHRoZSBiZXN0IHJlcG9ydGluZyBmaWRlbGl0eSBzaW5jZSBpdCdzIGEgRmlyc3QgT3JkZXIgU3RhdGlvbiBmb3IgTk9BQSwgYW5kIGZvciB5b3VyIHBlcmlvZCwgeW91IHdpbGwgd2FudCB0byB1c2UgdGhlIGZvbGxvd2luZyBzdGF0aW9uSUQgcGFpci4KCkkgYW0gbm90IHN1cmUgYXMgdG8gdGhlIHF1YWxpdHkgb3IgcmVsaWFiaWxpdHkgb2YgRWxzd29ydGggKEtSQ0EpLCBDdXN0ZXIgKEtDVVQpIG9yIFNwZWFyZmlzaCAoS1NQRikgc2luY2UgdGhleSBhcmUgbm90IGFmZmlsaWF0ZWQgd2l0aCBhbiBOV1Mgb2ZmaWNlLgoKYGBge3J9CmtyYXBfdXNhZiA9IDcyNjYyMAprcmFwX3diYW4gPSAgMjQwOTAKa3JhcF95ZWFyID0gICAyMDEwCgpzdGF0aW9uX25hbWVfbGFiZWwgPSBwYXN0ZSgiUmFwaWQgQ2l0eSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBrcmFwX3llYXIpCgpvdXRwdXRfZmlsZV9uYW1lID0gcGFzdGUoIktSQVAiLAogICAgICAgICAgICAgICAgICAgICAgICAga3JhcF95ZWFyLAogICAgICAgICAgICAgICAgICAgICAgICAgIi5jc3YiLAogICAgICAgICAgICAgICAgICAgICAgICAgc2VwPSIiKQoKYGBgCgpUbyBleHRyYWN0IHRoZSBkYXRhIChhbmQgdGhpcyBjYW4gdGFrZSBhIGZldyBtaW51dGVzIHNpbmNlIHlvdSBhcmUgZGlnZ2luZyBvbiB0aGUgTk9BQSBzZXJ2ZXJzLi4uKSAKCnVzZSB0aGUgaXNkIGNvbW1hbmQgZm9sbG93aW5nIHRoaXMgZXhhbXBsZS4gIFRoZSBvcmlnaW5hbCBkYXRhIGlzIGtlcHQgaW4gYSBjb21wcmVzc2VkICJ0YXJiYWxsIiB3aXRoIG9uZSB0YXJiYWxsIHBlciB5ZWFyLgoKVGhpcyBhbHNvIGhhcyB0aGUgb3B0aW9uIGZvciBtdWx0aXByb2Nlc3NpbmcgYnV0IHlvdSBwcm9iYWJseSBkb24ndCBuZWVkIGl0LgoKYGBge3J9CktSQVBfZGF0YSA9IGlzZCh1c2FmID0ga3JhcF91c2FmLCAgIyB5b3VyIHVzYWYgbnVtYmVyCiAgICAgICAgICAgICAgICB3YmFuID0ga3JhcF93YmFuLCAgIyB5b3VyIHdiYW4gbnVtYmVyCiAgICAgICAgICAgICAgICB5ZWFyID0ga3JhcF95ZWFyLCAgIyB5b3VyIHllYXIKICAgICAgICAgICAgICAgIHByb2dyZXNzPVRSVUUpICAgICAjIHNob3dzIHByb2dyYXNzIGFzIHlvdSBnbwoKcHJpbnQoS1JBUF9kYXRhKQoKYGBgCgoKCllvdSB3aWxsIHdhbnQgdG8gZml4IHRoZSBkYXRlLiAgSW4gdGhlIElTRCBmb3JtYXQgaXQgaXMgc3BsaXQgYmV0d2VlbiBjYWxlbmRhciBkYXkgKFVUQyB0aW1lIGFsd2F5cykgYW5kIGNsb2NrIGhvdXIgKFVUQyB0aW1lIGFsd2F5cykKClRoaXMgY2FuIGJlIGRvbmUgd2l0aCB0aGUgbHVicmlkYXRlIGZ1bmN0aW9uIHltZF9obSgpCgpgYGB7cn0KS1JBUF9kYXRhJGRhdGVfdGltZSA9IHltZF9obShzcHJpbnRmKCIlcyAlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMuY2hhcmFjdGVyKEtSQVBfZGF0YSRkYXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLUkFQX2RhdGEkdGltZSkpCgpLUkFQX2RhdGEkZGF0ZSA9IEtSQVBfZGF0YSRkYXRlX3RpbWUgCgpgYGAKCgoKClRoZSBkYXRhIGlzIHBhcnNlZCBhcyBzdHJpbmdzLiAgU28geW91J2xsIGhhdmUgdG8gdXNlIHRoZSBhcy5udW1lcmljKCkgYSBsb3QKTWlzc2luZyBmaWVsZHMgYXJlIHR5cGljYWxseSBJRCdlZCBhcyA5OTk5IGluIHRoZSBvcmlnaW5hbCBkYXRhCgpgYGB7cn0KCgpLUkFQX2RhdGEkdGVtcGVyYXR1cmVbS1JBUF9kYXRhJHRlbXBlcmF0dXJlID09ICIrOTk5OSJdICAgICAgICAgICAgICAgICAgID0gTkEgCgpLUkFQX2RhdGEkdGVtcGVyYXR1cmVfZGV3cG9pbnRbS1JBUF9kYXRhJHRlbXBlcmF0dXJlX2Rld3BvaW50ID09ICIrOTk5OSJdID0gTkEKCktSQVBfZGF0YSRhaXJfcHJlc3N1cmVbS1JBUF9kYXRhJGFpcl9wcmVzc3VyZSA9PSAiOTk5OTkiXSAgICAgICAgICAgICAgICAgPSBOQQoKS1JBUF9kYXRhJHdpbmRfc3BlZWRbS1JBUF9kYXRhJHdpbmRfc3BlZWQgPT0gIjk5OTkiXSAgICAgICAgICAgICAgICAgICAgID0gTkEKCktSQVBfZGF0YSR3aW5kX2RpcmVjdGlvbltLUkFQX2RhdGEkd2luZF9kaXJlY3Rpb24gPT0gIjk5OSJdICAgICAgICAgICAgID0gTkEKCgoKCmBgYAoKU29tZSBvZiB0aGVzZSBmaWVsZHMsIGJ1dCBub3QgYWxsLCBhcmUgbWFuYWdlZCB3aXRoIHRoZSBpc2RfdHJhbnNmb3JtKCkgZnVuY3Rpb24gd2l0aCByZXNwZWN0IHRvIHNjYWxpbmcKCnRlbXAvZGV3IHBvaW50IChkZWcgQykgY29udmVydGVkIGZyb20gMTB0aHMgb2YgZGVncmVlCm1lYW4gc2VhIGxldmVsIHByZXNzdXJlIChoUGEpIGNvbnZlcnRlZCBmcm9tIDEwdGhzIG9mIGhQYQp3aW5kIHNwZWVkICAgICAobSBzLTEpIGNvbnZlcnRlZCBmcm9tIDEwdGhzIG9mIG0gcy0xCndpbmQgZGlyZWN0aW9uIChjb21wYXNzIGRlY2ltYWwgZGVncmVlcykgCgpQcmVjaXAgaXMgYWxzbyBwcm9jZXNzZWQgYnV0IHRoaXMgZGF0YSBzZXQgaXMgYW4gbWVyZ2VyIG9mIGJvdGggaG91cmx5LCAzLWhybHksIDYtaHJseSwgMTItaHJseSwgMjQtaHJseSBkYXRhIGRlcGVuZGluZyBvbiB0aGUgcmVwb3J0IG1lc3NhZ2UgdGhhdCdzIGJlaW5nIGFyY2hpdmVkIGFuZCBJIGFtIG5vdCBzdXJlIHlvdSB3aWxsIHdhbnQgdGhhdCwgZXNwZWNpYWxseSBpZiB5b3UgY2FuIGdldCBIb3VybHkgUHJlY2lwIERhdGEgZnJvbSBhbm90aGVyIHNvdXJjZQoKYGBge3J9CgpLUkFQX2RhdGEgPSBpc2RfdHJhbnNmb3JtKEtSQVBfZGF0YSkKCiMgcGF0Y2ggdGhlIHdpbmQgZGlyZWN0aW9uIHNvIGl0J3MgMCBkZWdyZWVzIHdoZW4gdGhlIHdpbmQgc3BlZWQgaXMgbWlzc2luZwoKS1JBUF9kYXRhJHdpbmRfZGlyZWN0aW9uW0tSQVBfZGF0YSR3aW5kX3NwZWVkID09IDBdICAgICAgICAgICAgID0gMAoKCmBgYAoKCgpDbG91ZCBDb3ZlciBpcyBoZWxkIGluIHNldmVyYWwgcG9zaXRpb25zIGluIHRoZSBkYXRhc2V0LiAgT25jZSBhZ2FpbiB0aGlzIGlzIGJlY2F1c2UgdGhlIGRhdGEgaXMgZGVzaWduZWQgZm9yIHVzZSBmb3IgYWVyb2Ryb21lIHVzZS4gIAoKSSBhbSBzZXR0aW5nIGl0IHVwIHRvIGdpdmUgeW91IHRoZSAiR0YxIGdyb3VwIiB3aGljaCBpcyB0aGUgdG90YWwgY2xvdWQgY292ZXIgZm9yIGFsbCBmbGlnaHQgbGV2ZWxzLiAgVGhlc2UgZmllbGRzIGFyZSBvZnRlbiBhcmNoaXZlZCBpbiAib2N0YXZlcyIgb3IgZWlnaHRzIGFuZCBJJ2xsIGJlIGNvbnZlcnRpbmcgdGhlbSB0byBmcmFjdGlvbnMgZm9yIHlvdS4gIElOIGNhc2VzIG9mICJvYnNjdXJlZCBza3kiIGNhdXNlZCBieSBmb2cgb3Igc21va2UsIEkgd2lsbCBsYWJlbCBpdCAxMDAlIGZvciB0b3RhbCBvYnNjdXJlZCBza3kgb3IgNTAlIGNvdmVyZWQgZm9yIHBhcnRpYWwgb2JzY3VyZWQgc2tpZXMuICAgIAoKCmBgYHtyfQoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbiA9IGFzLm51bWVyaWMoS1JBUF9kYXRhJEdGMV9jb3ZlcmFnZSkKCiMgMDA6IE5vbmUsIFNLQyBvciBDTFIKCktSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb25bS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbj09MDBdID0gMC4wMAoKIyAwMTogT25lIG9rdGEgLSAxLzEwIG9yIGxlc3MgYnV0IG5vdCB6ZXJvCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTAxXSA9IDEuMCAvIDguMAoKIyAwMjogVHdvIG9rdGFzIC0gMi8xMCDigJEgMy8xMCwgb3IgRkVXCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTAyXSA9IDIuMCAvIDguMAoKIyAwMzogVGhyZWUgb2t0YXMgLSA0LzEwCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTAzXSA9IDMuMCAvIDguMAoKIyAwNDogRm91ciBva3RhcyAtIDUvMTAsIG9yIFNDVAoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbltLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uPT0wNF0gPSA0LjAgLyA4LjAKCiMgMDU6IEZpdmUgb2t0YXMgLSA2LzEwCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTA1XSA9IDUuMCAvIDguMAoKIyAwNjogU2l4IG9rdGFzIC0gNy8xMCDigJEgOC8xMAoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbltLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uPT0wNl0gPSA2LjAgLyA4LjAKCiMgMDc6IFNldmVuIG9rdGFzIC0gOS8xMCBvciBtb3JlIGJ1dCBub3QgMTAvMTAsIG9yIEJLTgoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbltLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uPT0wN10gPSA3LjAgLyA4LjAKCiMgMDg6IEVpZ2h0IG9rdGFzIC0gMTAvMTAsIG9yIE9WQwoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbltLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uPT0wOF0gPSA4LjAgLyA4LjAKCiMgMDk6IFNreSBvYnNjdXJlZCwgb3IgY2xvdWQgYW1vdW50IGNhbm5vdCBiZSBlc3RpbWF0ZWQKCktSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb25bS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbj09MDldID0gOC4wIC8gOC4wCgojIDEwOiBQYXJ0aWFsIG9ic2N1cmF0aW9uCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTEwXSA9IDQuMCAvIDguMAoKIyAxMTogVGhpbiBzY2F0dGVyZWQKCktSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb25bS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbj09MTFdID0gMi4wIC8gOC4wCgojIDEyOiBTY2F0dGVyZWQKCktSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb25bS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbj09MTJdID0gNC4wIC8gOC4wCgojIDEzOiBEYXJrIHNjYXR0ZXJlZAoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbltLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uPT0xM10gPSA1LjAgLyA4LjAKCiMgMTQ6IFRoaW4gYnJva2VuCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTE0XSA9IDYuMCAvIDguMAoKIyAxNTogQnJva2VuCgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTE1XSA9IDcuMCAvIDguMAoKIyAxNjogRGFyayBicm9rZW4KCktSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb25bS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbj09MTZdID0gOC4wIC8gOC4wCgojIDE3OiBUaGluIG92ZXJjYXN0CgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTE3XSA9IDQuMCAvIDguMAoKIyAxODogT3ZlcmNhc3QKCktSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb25bS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbj09MThdID0gOC4wIC8gOC4wCgojIDE5OiBEYXJrIG92ZXJjYXN0CgpLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uW0tSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb249PTE5XSA9IDguMCAvIDguMAoKIyA5OTogTWlzc2luZwoKS1JBUF9kYXRhJEdGMV90b3RhbF9jbG91ZF9jb3Zlcl9mcmFjdGlvbltLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uPT05OV0gPSBOQQoKCmBgYAoKCkFuZCB0byBwbG90IGV2ZXJ5dGhpbmcgb3V0Li4uCgpUZW1wZXJhdHVyZQoKYGBge3J9CgpwbG90KHggICAgICAgPSBLUkFQX2RhdGEkZGF0ZV90aW1lLAogICAgIHkgICAgICAgPSBLUkFQX2RhdGEkdGVtcGVyYXR1cmUsIAogICAgIHR5cGUgICAgPSAibCIsIAogICAgIGNvbCAgICAgPSAicmVkIiwgCiAgICAgbHdkICAgICA9IDEuNSwgCiAgICAgY2V4LmxhYiA9IDEuMjUsCiAgICAgeGxhYiAgICA9ICJEYXRlIiwgCiAgICAgeWxhYiAgICA9ICJUZW1wZXJhdHVyZSAoZGVnIEMpIiwKICAgICBtYWluICAgID0gc3RhdGlvbl9uYW1lX2xhYmVsKQoKYGBgCgoKRGV3IFBvaW50CgpgYGB7cn0KCgpwbG90KHggICAgICAgPSBLUkFQX2RhdGEkZGF0ZV90aW1lLAogICAgIHkgICAgICAgPSBLUkFQX2RhdGEkdGVtcGVyYXR1cmVfZGV3cG9pbnQsIAogICAgIHR5cGUgICAgPSAibCIsIAogICAgIGNvbCAgICAgPSAiZGFya2dyZWVuIiwgCiAgICAgbHdkICAgICA9IDEuNSwgCiAgICAgY2V4LmxhYiA9IDEuMjUsCiAgICAgeGxhYiAgICA9ICJEYXRlIiwgCiAgICAgeWxhYiAgICA9ICJEZXcgUG9pbnQgKGRlZyBDKSIsCiAgICAgbWFpbiAgICA9IHN0YXRpb25fbmFtZV9sYWJlbCkKCmBgYAoKQ2xvdWQgRnJhY3Rpb24gCmBgYHtyfQoKCnBsb3QoeCAgICAgICA9IEtSQVBfZGF0YSRkYXRlX3RpbWUsCiAgICAgeSAgICAgICA9IEtSQVBfZGF0YSRHRjFfdG90YWxfY2xvdWRfY292ZXJfZnJhY3Rpb24sIAogICAgIHR5cGUgICAgPSAibCIsIAogICAgIGNvbCAgICAgPSAiZ3JleSIsIAogICAgIGx3ZCAgICAgPSAxLjUsIAogICAgIGNleC5sYWIgPSAxLjI1LAogICAgIHhsYWIgICAgPSAiRGF0ZSIsIAogICAgIHlsYWIgICAgPSAiQ2xvdWQgQ292ZXIgKGZyYWN0aW9uKSIsCiAgICAgbWFpbiAgICA9IHN0YXRpb25fbmFtZV9sYWJlbCkKCmBgYAoKCgoKUHJlc3N1cmUgCgpgYGB7cn0KCgpwbG90KHggICAgICAgPSBLUkFQX2RhdGEkZGF0ZV90aW1lLAogICAgIHkgICAgICAgPSBLUkFQX2RhdGEkYWlyX3ByZXNzdXJlLCAKICAgICB0eXBlICAgID0gImwiLCAKICAgICBjb2wgICAgID0gImJsdWUiLCAKICAgICBsd2QgICAgID0gMS41LCAKICAgICBjZXgubGFiID0gMS4yNSwKICAgICB4bGFiICAgID0gIkRhdGUiLCAKICAgICB5bGFiICAgID0gIk1TTCBQcmVzc3VyZSAobWIpIiwKICAgICBtYWluICAgID0gc3RhdGlvbl9uYW1lX2xhYmVsKQoKYGBgCgoKCldpbmQgU3BlZWQgCgpgYGB7cn0KCgpwbG90KHggICAgICAgPSBLUkFQX2RhdGEkZGF0ZV90aW1lLAogICAgIHkgICAgICAgPSBLUkFQX2RhdGEkd2luZF9zcGVlZCwgCiAgICAgdHlwZSAgICA9ICJsIiwgCiAgICAgY29sICAgICA9ICJkYXJrYmx1ZSIsIAogICAgIGx3ZCAgICAgPSAxLjUsIAogICAgIGNleC5sYWIgPSAxLjI1LAogICAgIHhsYWIgICAgPSAiRGF0ZSIsIAogICAgIHlsYWIgICAgPSAiV2luZCBTcGVlZCAobSBzLTEpIiwKICAgICBtYWluICAgID0gc3RhdGlvbl9uYW1lX2xhYmVsKQoKYGBgCgoKV2luZCBSb3NlIAoKYGBge3J9Cgp3aW5kcm9zZV9mcmFtZSA9IGRhdGEuZnJhbWUoZGF0ZSAgICAgID0gS1JBUF9kYXRhJGRhdGVfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdzICAgICAgICA9IEtSQVBfZGF0YSR3aW5kX3NwZWVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2QgICAgICAgID0gS1JBUF9kYXRhJHdpbmRfZGlyZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZ2l0dWRlID0gS1JBUF9kYXRhJGxvbmdpdHVkZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlICA9IEtSQVBfZGF0YSRsYXRpdHVkZSkKCgoKd2luZFJvc2UobXlkYXRhICAgICA9IHdpbmRyb3NlX2ZyYW1lLCAKICAgICAgICAgd3MgICAgICAgICA9ICJ3cyIsIAogICAgICAgICB3ZCAgICAgICAgID0gIndkIiwKICAgICAgICAgdHlwZSAgICAgICA9ICJ5ZWFyIiwKICAgICAgICAgaGVtaXNwaGVyZSA9ICJub3J0aGVybiIsCiAgICAgICAgIG1haW4gICAgICAgPSBzdGF0aW9uX25hbWVfbGFiZWwpCgoKd2luZFJvc2UobXlkYXRhICAgICA9IHdpbmRyb3NlX2ZyYW1lLCAKICAgICAgICAgd3MgICAgICAgICA9ICJ3cyIsIAogICAgICAgICB3ZCAgICAgICAgID0gIndkIiwKICAgICAgICAgdHlwZSAgICAgICA9ICJzZWFzb24iLAogICAgICAgICBoZW1pc3BoZXJlID0gIm5vcnRoZXJuIiwKICAgICAgICAgbWFpbiAgICAgICA9IHN0YXRpb25fbmFtZV9sYWJlbCkKCgpgYGAKCkZpbmFsbHkgbGV0J3MgcHV0IGV2ZXJ5dGhpbmcgaW50byBhIHNpbmdsZSB0aW1lIGZyYW1lIHNpbmNlIHdlIGhhdmUgb2JzZXJ2YXRpb25zIGF0IHNldmVyYWwgdGltZXMuICBXZSBjYW4gaW50ZXJwb2xhdGUgdGhlIGRhdGEgdG8gdGhlIG5lYXJlc3QgaG91ci4KCldlIGRvIHRoaXMgYnkgZmlyc3QgY3JlYXRpbmcgYSByZWd1bGFybHkgc3BhY2VkIHRpbWUgdmVjdG9yCgoKYGBge3J9CgpzdGFydF9kYXRlID0gYXMuUE9TSVhjdChwYXN0ZShrcmFwX3llYXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItMDEtMDEgMDA6MDA6MDAgVVRDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwPSIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgdHogPSAiVVRDIikKCmVuZF9kYXRlICAgPSBhcy5QT1NJWGN0KHBhc3RlKGtyYXBfeWVhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi0xMi0zMSAwMDowMDowMCBVVEMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXA9IiIpLAogICAgICAgICAgICAgICAgICAgICAgICB0eiA9ICJVVEMiKQoKaG91cl90aW1lID0gc2VxLlBPU0lYdChmcm9tID0gc3RhcnRfZGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdG8gICA9IGVuZF9kYXRlLAogICAgICAgICAgICAgICAgICAgICAgICBieSAgID0gIjEgaG91ciIsCiAgICAgICAgICAgICAgICAgICAgICAgIHR6ICAgPSAiVVRDIikKCgoKYGBgCgpXZSB0aGVuIGludGVycG9sYXRlIGJldHdlZW4gdGhlIHZhcmlvdXMgZmllbGRzIGFuZCBmcmFtZSB0aGVtLi4uIAoKYGBge3J9CgpLUkFQX3RpbWVfc2VyaWVzICAgICAgICAgICAgICAgICAgPSBkYXRhLmZyYW1lKGRhdGUgPSBob3VyX3RpbWUpCgpLUkFQX3RpbWVfc2VyaWVzJHRlbXBlcmF0dXJlX2RlZ0MgPSBhcHByb3goeCAgICAgID0gS1JBUF9kYXRhJGRhdGVfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgICAgICA9IEtSQVBfZGF0YSR0ZW1wZXJhdHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJsaW5lYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG91dCAgID0gaG91cl90aW1lKSR5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApLUkFQX3RpbWVfc2VyaWVzJGRld3BvaW50X2RlZ0MgICAgPSBhcHByb3goeCAgICAgID0gS1JBUF9kYXRhJGRhdGVfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgICAgICA9IEtSQVBfZGF0YSR0ZW1wZXJhdHVyZV9kZXdwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJsaW5lYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG91dCAgID0gaG91cl90aW1lKSR5IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKS1JBUF90aW1lX3NlcmllcyRjbG91ZF9mcmFjdGlvbiAgID0gYXBwcm94KHggICAgICA9IEtSQVBfZGF0YSRkYXRlX3RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ICAgICAgPSBLUkFQX2RhdGEkR0YxX3RvdGFsX2Nsb3VkX2NvdmVyX2ZyYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gImxpbmVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4b3V0ICAgPSBob3VyX3RpbWUpJHkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApLUkFQX3RpbWVfc2VyaWVzJHByZXNzX21zbF9oUGEgICAgPSBhcHByb3goeCAgICAgID0gS1JBUF9kYXRhJGRhdGVfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgICAgICA9IEtSQVBfZGF0YSRhaXJfcHJlc3N1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAibGluZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhvdXQgICA9IGhvdXJfdGltZSkkeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKS1JBUF90aW1lX3NlcmllcyR3aW5kX3NwZF9tcyAgICAgID0gYXBwcm94KHggICAgICA9IEtSQVBfZGF0YSRkYXRlX3RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ICAgICAgPSBLUkFQX2RhdGEkd2luZF9zcGVlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJsaW5lYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG91dCAgID0gaG91cl90aW1lKSR5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApLUkFQX3RpbWVfc2VyaWVzJHdpbmRfZGlyX2RlZ3JlZXMgID0gYXBwcm94KHggICAgID0gS1JBUF9kYXRhJGRhdGVfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgICAgICA9IEtSQVBfZGF0YSR3aW5kX2RpcmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJsaW5lYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG91dCAgID0gaG91cl90aW1lKSR5CgoKCnByaW50KEtSQVBfdGltZV9zZXJpZXMpCmBgYAoKQW5kIHNlbmQgaXQgdG8gYW4gQVNDSUkgZmlsZQoKYGBge3J9CgoKd3JpdGUudGFibGUoeCAgICA9IEtSQVBfdGltZV9zZXJpZXMsIAogICAgICAgICAgICBmaWxlID0gb3V0cHV0X2ZpbGVfbmFtZSwgCiAgICAgICAgICAgIHNlcCAgPSIsICIsCiAgICAgICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgo=